package com.quectel.grid.controller.really;

import cn.hutool.core.lang.func.LambdaUtil;
import com.quectel.business.common.grid.GridMemberBindResourcesBusiness;
import com.quectel.constant.core.grid.GridConstant;
import com.quectel.constant.global.SystemConstants;
import com.quectel.core.module.grid.dto.GridBindingDto;
import com.quectel.core.module.grid.dto.GridDto;
import com.quectel.core.module.grid.dto.GridMemberDto;
import com.quectel.core.module.grid.service.GridBindingService;
import com.quectel.core.module.grid.service.GridService;
import com.quectel.core.module.really.dto.ReallyCompanyDto;
import com.quectel.core.module.really.service.ReallyCompanyService;
import com.quectel.grid.controller.BaseController;
import com.quectel.grid.interceptor.LoginGridMemberSession;
import com.quectel.grid.util.SessionHolder;
import com.quectel.grid.vo.reallycompany.ReallyCompanyResp;
import com.quectel.grid.vo.reallycompany.ReallyCompanyVo;
import com.quectel.util.common.CopyUtils;
import com.quectel.util.common.Page;
import com.quectel.util.common.Request;
import com.quectel.util.common.Response;
import com.quectel.util.ex.CheckErrorException;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.*;

/**
 * 在这里编写说明
 *
 * @author: bob
 * @email: bob.yu@quectel.com
 * @date: 2023-02-16 10:07:00
 */
@RestController
@RequestMapping("reallyCompany")
@Tag(name = "ReallyCompanyController", description = "实有单位相关的api")
public class ReallyCompanyController extends BaseController {

    public static final String COMPANY_IDS = "companyIds";

    @DubboReference
    private ReallyCompanyService reallyCompanyService;
    @DubboReference
    private GridService gridService;
    @DubboReference
    private GridBindingService gridBindingService;

    @Autowired
    private GridMemberBindResourcesBusiness gridMemberBindResourcesBusiness;

    @PostMapping("update")
    @Operation(summary = "修改单条记录")
    public Response<Object> update(@RequestBody @Validated ReallyCompanyVo reallyCompanyVo) {
        LoginGridMemberSession loginGridUserSession = SessionHolder.getLoginGridUserSession();
        GridMemberDto gridMember = loginGridUserSession.getGridMember();


        if (reallyCompanyVo.getId() == null) {
            return Response.error(SystemConstants.ILLEGAL_MSG);
        }
        ReallyCompanyDto reallyCompanyDto = CopyUtils.copyObj(reallyCompanyVo, ReallyCompanyDto.class);
        reallyCompanyDto.setEditor(gridMember.getName());
        reallyCompanyDto.setEditTime(new Date());
        reallyCompanyService.updateById(reallyCompanyDto);
        return Response.ok();
    }


    /**
     * 信息
     */
    @GetMapping("info/{id}")
    @Operation(summary = "查询单条记录")
    public Response<ReallyCompanyResp> info(@PathVariable("id") Long id) {

        LoginGridMemberSession loginGridUserSession = SessionHolder.getLoginGridUserSession();

        ReallyCompanyDto reallyCompanyDto = reallyCompanyService.selectById(id);
        ReallyCompanyResp reallyCompanyResp = CopyUtils.copyObj(reallyCompanyDto, ReallyCompanyResp.class);
        GridBindingDto binding =
                gridBindingService.selectOne(GridConstant.SourceType.COMPANY.getType(), reallyCompanyDto.getId());
        if (binding != null) {
            GridDto grid = gridService.selectCacheById(binding.getGridId());
            if (grid != null) {
                reallyCompanyResp.setGridId(grid.getId());
                reallyCompanyResp.setGridName(grid.getName());
            }
        }
        return Response.<ReallyCompanyResp>ok().wrap(reallyCompanyResp);
    }

    @PostMapping("save")
    @Operation(summary = "新增实有单位")
    public Response<Object> save(@RequestBody ReallyCompanyVo reallyCompanyVo) {
        LoginGridMemberSession loginGridUserSession = SessionHolder.getLoginGridUserSession();
        GridMemberDto gridMember = loginGridUserSession.getGridMember();

        try {
            GridDto gridDto = gridService.selectById(reallyCompanyVo.getGridId());
            ReallyCompanyDto reallyCompanyDto = CopyUtils.copyObj(reallyCompanyVo, ReallyCompanyDto.class);
            reallyCompanyDto.setTenantId(gridDto.getTenantId());
            reallyCompanyDto.setVillageId(gridDto.getVillageId());
            reallyCompanyDto.setCreator(gridMember.getName());
            reallyCompanyDto.setCreateTime(new Date());

            Long save = reallyCompanyService.save(reallyCompanyDto);

            // 校验关系是否存在
            Map<String, Object> sqlMap = new HashMap<>();
            sqlMap.put(LambdaUtil.getFieldName(GridBindingDto::getGridId), gridDto.getId());
            sqlMap.put(LambdaUtil.getFieldName(GridBindingDto::getSourceType), GridConstant.SourceType.COMPANY.getType());
            sqlMap.put(LambdaUtil.getFieldName(GridBindingDto::getSourceId), save);

            int total = gridBindingService.queryTotal(sqlMap);
            if (total > 0) {
                throw new CheckErrorException("网格绑定单位关联关系已存在");
            } else {
                // 保存关联关系
                GridBindingDto bindingDto = new GridBindingDto();
                bindingDto.setGridId(gridDto.getId());
                bindingDto.setSourceType(GridConstant.SourceType.COMPANY.getType());
                bindingDto.setSourceId(save);
                gridBindingService.save(bindingDto);
            }

        } catch (Exception e) {
            logger.error("网格员新增单位失败", e);
        }

        return Response.ok();
    }


    @GetMapping("list")
    @Operation(summary = "查询实有单位列表")
    public Response<Page<ReallyCompanyResp>> list(
            @Parameter(description = "单位名称") @RequestParam(required = false) String name,
            @Parameter(description = "网格id") @RequestParam(required = false) Long gridId,
            @Parameter(description = "从1开始的页码数") @RequestParam Integer pageNo,
            @Parameter(description = "每页多少条") @RequestParam Integer pageSize) {
        LoginGridMemberSession loginGridUserSession = SessionHolder.getLoginGridUserSession();
        //查询列表数据


        Request request = Request.configParams(Request.parseParams(httpServletRequest));
        List<Long> sourceIds = new ArrayList<>();
        // 精准网格
        if (gridId != null) {
            sourceIds = gridMemberBindResourcesBusiness.getSourceIdByGridIdAndSourceType(gridId, GridConstant.SourceType.COMPANY.getType());
        } else {
            // 用户权限下所有网格
            GridMemberDto gridMember = loginGridUserSession.getGridMember();
            sourceIds = gridMemberBindResourcesBusiness.getSourceIdByMemberIdAndSourceType(gridMember.getId(), GridConstant.SourceType.COMPANY.getType());
        }
        request.getParams().put(COMPANY_IDS, sourceIds);
        int total = reallyCompanyService.queryTotal(request.getParams());
        List<ReallyCompanyDto> list = null;
        List<ReallyCompanyResp> recordList = new ArrayList<>();
        if (total > 0) {
            list = reallyCompanyService.queryList(request.getParams());
            for (ReallyCompanyDto reallyCompanyDto : list) {
                ReallyCompanyResp reallyCompanyResp = CopyUtils.copyObj(reallyCompanyDto, ReallyCompanyResp.class);
                GridBindingDto binding =
                        gridBindingService.selectOne(GridConstant.SourceType.COMPANY.getType(), reallyCompanyDto.getId());
                if (binding != null) {
                    GridDto grid = gridService.selectCacheById(binding.getGridId());
                    if (grid != null) {
                        reallyCompanyResp.setGridId(grid.getId());
                        reallyCompanyResp.setGridName(grid.getName());
                    }
                }
                recordList.add(reallyCompanyResp);
            }
        } else {
            list = new ArrayList<>();
        }

        Page<ReallyCompanyResp> page = new Page<>(request.getPageNo(), request.getPageSize(), total, recordList);
        return Response.<Page<ReallyCompanyResp>>ok().wrap(page);
    }

}
